<?php

function start_with($str, $needle) {
    return strpos($str, $needle) === 0;
}

function end_with($haystack, $needle) {   
    $length = strlen($needle);  
    if($length == 0) {    
        return true;  
    }
    return (substr($haystack, -$length) === $needle);
}
/**
 * 根据键名保留对应的元素
 */
function array_keep(array $array, array $fields)
{
    return array_intersect_key($array, array_flip($fields));
}

function list_keep(array $array, array $fields)
{
    $list = $array;
    foreach ($list as &$item) {
        $item = array_keep($item, $fields);
    }
    return $list;
}

function array_group_by(array $list, $groupName, $name = 'name', $childrenName = 'items')
{
    $groupList = [];
    $group = array_group($list, $groupName);
    foreach ($group as $gname => $items) {
        $groupList[] = [
            'name' => $gname,
            'items' => $items,
        ];
    }
    return $groupList;

}

/**
 * 根据array的某一属性分组
 * @param  array  $list      arraylist
 * @param  string $groupName 数组的某一元素
 * @return array             分组后的数组
 */
function array_group(array $list, $groupName)
{
    $groups = array_column($list, $groupName);
    $groupDict = array_fill_keys($groups, []);
    foreach ($list as $item) {
        $groupDict[$item[$groupName]][] = $item;
    }
    return $groupDict;
}

/**
 * 提取列的地址
 *
 * @param array $array
 * @param [type] $column
 * @return void
 */
function array_column_link(array &$array, $column)
{
    $links = [];
    foreach ($array as &$item) {
        $links[] = &$item[$column];
    }
    return $links;
}

/**
 * 获取服务器host，兼容代理
 *
 * @return void
 */
function get_host()
{
    $host = isset($_SERVER['HTTP_X_FORWARDED_HOST']) ? $_SERVER['HTTP_X_FORWARDED_HOST'] : (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '');
    return is_ssl() ? 'https://' : 'http://' . $host;
}

/**
 * 加强U方法，与U方法相比，该方法支持调用不同入口文件
 *
 * @param string       $url    URL表达式，格式：'[入口文件名::模块/控制器/操作#锚点@域名]?参数1=值1&参数2=值2...',如admin::Admin/User/hello
 * @param string|array $vars   传入的参数，支持数组和字符串
 * @param string|bool  $suffix 伪静态后缀，默认为true表示获取配置值
 * @param bool         $domain 是否显示域名
 *
 * @return string
 */
function url($url = '', $vars = '', $suffix = true, $domain = false)
{
    if (strpos($url, '::')) {
        list($project_name, $module_url) = explode('::', $url);

        return preg_replace('/[a-zA-Z0-9_]+\.php/', $project_name.'.php', U($module_url, $vars, $suffix, $domain));
    } else {
        return U($url, $vars, $suffix, $domain);
    }
}

/**
 * 自动补充域名
 *
 * @param string $resourcePath
 * @return void
 */
function auto_prefix($path, $host = null)
{
    $host = $host ?: get_host();
    if (preg_match('/^(http:\/\/)|^(https:\/\/)/', $path) === 0) {
        return $host . '/' . trim($path, '/');
    } else {
        return $path;
    }
}

/**
 * 保存文件到相关路径
 * @todo 支持上传到第三方应用
 * @todo 配置文件放置到外部
 *
 * @param string $type
 * @param [type] $error
 * @return array [name] => ['pics']
 */
function save_files($type = 'image', &$error)
{
    $restype = I('post.restype', 'image');
    $config = [
        'maxSize'    =>    1024 * 1024 * 5,
        'rootPath'   =>    './Uploads/',
        'savePath'   =>    "$type/",
        'saveName'   =>    ['uuid'],
        'exts'       =>    ['jpg', 'gif', 'png', 'jpeg'],
        'autoSub'    =>    true,
        'subName'      =>  strval(time()),
    ];
    $driver = C('UPLOAD_TYPE_CONFIG');
    $driverConfig = $driver === 'Local' ? null : C('SDK_' . $driver);
    $upload = new \Think\Upload($config, $driver, $driverConfig);
    $fileinfos = $upload->upload();
    if(!$fileinfos) {
        $error = $upload->getError();
        return false;
    }else{
        return array_map(function($fileinfo) use ($upload) {
            /* 理论上不应该把 upload 的目录放到这里
                upload路径应该在地址补全时才放入，
                上传到第三方的存储空间时，此处需要改动*/
            return trim($upload->rootPath.$fileinfo['savepath'].$fileinfo['savename'], '.');
        }, $fileinfos);
    }
}

/**
 * 生成uuid主键
 * 为了方便调用
 *
 * @return string
 */
function uuid()
{
    return \Util\StringUtils::keyGen();
}

/**
 * 兼容nginx服务器
 */
if (!function_exists('getallheaders'))
{
    function getallheaders()
    {
           $headers = [];
       foreach ($_SERVER as $name => $value)
       {
           if (substr($name, 0, 5) == 'HTTP_')
           {
               $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
           }
       }
       return $headers;
    }
}


function pagination($total_rows, $per_page, $current_page)
{

    /* 计算分页信息 */
    $total_pages = ceil($total_rows / $per_page); //总页数

    return [
        'total_row' => $total_rows,
        'total_page' => $total_pages,
        'current_page' => $current_page,
    ];
}

/**
 * 过滤变量，提取自I方法
 *
 * @param mixed $data
 * @param string $default
 * @param array $filters
 * @return mixed
 */
function filter($data, $default = '', $filters = [])
{
    $data = $data ?: $default;
    if ($filters && is_array($filters)) {
        foreach ($filters as $filter) {
            if (function_exists($filter)) {
                $data = is_array($data) ? array_map_recursive($filter, $data) : $filter($data); // 参数过滤
            } else {
                $data = filter_var($data, is_int($filter) ? $filter : filter_id($filter));
                if (false === $data) {
                    return isset($default) ? $default : null;
                }
            }
        }
    }
    return $data;
}

/**
 * 获取当前登录用户信息
 *
 * @param string $module 模块名，可在config.php配置默认
 * @return array
 */
function user($module = null)
{
    return \Auth\Auth::auth($module)->user();
}

// 简写版transform
function transform($trans_name, $name, $data)
{
    $trans_class = "\\Transform\\{$trans_name}Transform";
    return $trans_class::instance()->trans($name, $data);
}

function object_to_array($obj)
{
    return json_decode(json_encode($obj), true);
}

function get_extension($file)
{
    return substr(strrchr($file, '.'), 0);
}


/**
 * 自动填充oss image样式
 * @param  string $url    图片路径
 * @param  array  $styles 样式名称，需要确保oss已设置该样式
 * @return [type]         [description]
 */
function oss_images_auto_fill($url, array $styles)
{
    $urls = [];
    $urls['origin'] = $url . '?x-oss-process=style/' . 'shuiyin';
    foreach ($styles as $style) {
        $urls[$style] = $url . '?x-oss-process=style/' . $style;
    }
    return $urls;
}

/* 获取当前token的用户 */
function get_user()
{
    $headers = getallheaders();
    if (array_key_exists('Authorization', $headers)) {
        $token = $headers['Authorization'];
        try {
            $user = \Firebase\JWT\JWT::decode($token, C('AUTH_KEY'), ['HS256']);
            $user = object_to_array($user);
            $user['id'] = $user['user_id'];
            return $user;
        } catch (\Firebase\JWT\SignatureInvalidException $e) {
        } catch (\Firebase\JWT\BeforeValidException $e) {
        } catch (\Exception $e) {
        }
    } else {
        return null;
    }
}

/**
 * 初始化redis
 *
 * @return void
 */
function redis()
{
    $redis = new Redis();
    $redis->connect(C('REDIS_HOST'), C('REDIS_PORT'));
    if (C('REDIS_AUTH')) $redis->auth(C('REDIS_AUTH'));
    return $redis;
}

/**
 * 判断等级
 *
 * @param integer $score 当前分数
 * @param array $levelDict 分数线的关联数组，[1 => 100, 2 => 300],代表 [100, 300)为1级 [300, 正无穷]为2级
 * @return void
 */
function level($score, $levelDict)
{
    arsort($levelDict, SORT_NUMERIC);
    foreach ($levelDict as $level => $minScore) {
        if ($score >= $minScore) {
            return $level;
        }
    }
    return 0;
}

/**
 * 粗糙的敏感词过滤，不适合作长文本过滤
 *
 * @param string $str 要过滤的字符串
 * @param array $words 敏感词数组
 * @return string
 */
function filter_badwords($str, $words = [])
{
    $replaces = array_map(function($val) {
        return str_repeat('*', mb_strlen($val));
    }, $words);
    return str_replace($words, $replaces, $str);
}

/**
 * 提取html代码中的图片链接
 * @param  string $html html文本
 * @return array       图片链接
 */
function extract_html_images($html)
{
    $pattern ='<img.*?src="(.*?)">';
    preg_match_all($pattern,$html,$matches);
    return empty($matches[1]) ? [] : $matches[1];
}

function array_keys_map($callback, $array) 
{
    $keys = array_keys($array);
    $values = array_values($array);
    $keys = array_map($callback, $keys);
    return array_combine($keys, $values);
}

function lock($sign, $callback)
{
    $dir = PROJECT_PATH . '/locks';
    if (!file_exists($dir)) {
        mkdir($dir, 0777, true);
    }
    $file = $dir . '/' . $sign;
    file_put_contents($file, '1');
    $fp = fopen($file, 'w');
    if (flock($fp, LOCK_EX)) {
        $rst = $callback();
        flock($fp, LOCK_UN);
        fclose($fp);
        unlink($file);
        return $rst;
    } else {
        fclose($fp);
        return false;
    }
}

function file_lock($sign)
{
    $dir = PROJECT_PATH . '/locks';
    if (!file_exists($dir)) {
        mkdir($dir, 0777, true);
    }
    $file = $dir . '/' . $sign;
    if (file_exists($file)) {
        return false;
    } else {
        return !! file_put_contents($file, '1', LOCK_EX);
    }
}

function file_unlock($sign)
{
    $dir = PROJECT_PATH . '/locks';
    $file = $dir . '/' . $sign;
    if (file_exists($file)) {
        return unlink($file);
    }
    return false;

}

function isMail($email) {
	$pattern = "/\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/";
	if(preg_match($pattern,$email)){
		return true;
	}else{
		return false;
	}
}

function isMobile($mobile){
    $pattern = '/^1[34578]{1}\d{9}$/';
    if(preg_match($pattern, $mobile)){
    if(preg_match($pattern, $mobile)){
        return TRUE;
    }
    return FALSE;
    }
}

    /**
 * 判断一个字符串是否是一个Email地址
 *
 * @param string $string
 * @return boolean
 */
function isEmail($string) {
    return (boolean) preg_match('/^[a-z0-9.\-_]{2,64}@[a-z0-9]{2,32}(\.[a-z0-9]{2,5})+$/i', $string);
}